﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using System.Configuration;
using System.Threading;
using System.ServiceModel;
using BoardPACUtil.Util;

namespace BoardPACDSWS.General.Logs
{
    /// <summary>
    ///  <title>Custom Log Class class</title>
    ///  <description></description>
    ///  <copyRight>Copyright (c) 2012</copyRight>
    ///  <company>IronOne Technologies (Pvt)Ltd</company>
    ///  <createdOn>2012-</createdOn>
    ///  <author></author>
    ///  <modification>
    ///     <modifiedBy></modifiedBy>
    ///      <modifiedDate></modifiedDate>
    ///     <description></description>
    ///  </modification>
    /// </summary>
    public class Logs
    {
        private static Logs loggerHandler;

        #region Loggers
        //private static Logger _dbLogger;
        //public static Logger DBErrorLogger
        //{
        //    get
        //    {
        //        if (_dbLogger == null)
        //        {
        //            _dbLogger = GetLogger("DBErrorLogger");
        //        }
        //        return _dbLogger;
        //    }
        //}

        private static Loggers _errorLogger;
        public static Loggers ErrorLogger
        {
            get
            {
                if (_errorLogger == null || _errorLogger.loggers == null)
                {
                    _errorLogger = GetLogger("errorLoggers");
                }
                return _errorLogger;
            }
        }

        private static Loggers _eventLogger;
        public static Loggers EventLogger
        {
            get
            {
                if (_eventLogger == null || _eventLogger.loggers == null)
                {
                    _eventLogger = GetLogger("eventLoggers");
                }
                return _eventLogger;
            }
        }

        #endregion

        public static Loggers GetLogger(string loggersName)
        {
            string loggers = ConfigurationManager.AppSettings[loggersName];
            Loggers loggerObjs = new Loggers();
            foreach (string item in loggers.Split(';'))
            {
                try
                {
                    log4net.ILog log = log4net.LogManager.GetLogger(item);
                    Logger logger = new Logger(log);
                    loggerObjs.AddLogger(logger);
                }
                catch (Exception)
                {
                    continue;
                } 
            }
            return loggerObjs;
        }
        private Logs()
        {

        }
        public static Logs GetInstance()
        {
            if (loggerHandler == null)
            {
                loggerHandler = new Logs();
            }
            return loggerHandler;
        }
    }

    public class Loggers
    {
        public List<Logger> loggers;

        public void AddLogger(Logger logger)
        {
            if (loggers == null)
            {
                loggers = new List<Logger>();
            }
            loggers.Add(logger);
        }

        public void Log(object message, Exception exception)
        {
            LogObj obj = new LogObj() { Message = message, Exception = exception };
            ThreadPool.QueueUserWorkItem(new WaitCallback(AddLog), obj);
        }

        private void AddLog(object logObj)
        {
            LogObj obj = (LogObj)logObj;
            foreach (Logger item in loggers)
            {
                item.Log(obj.Message, obj.Exception);
            }
        }

        public void Log(object message)
        {
            this.Log(message, null);
        }

        public class LogObj
        {
            public object Message { get; set; }
            public Exception Exception { get; set; }
        }

        public void WriteLog(LogPoint logpoint)
        {
            Log("0," + logpoint.ToString() + "," + Utility.GetAction(OperationContext.Current.IncomingMessageHeaders.Action) + "," + Global.UserName + ",Params(" + Utility.GetParams(OperationContext.Current.RequestContext.RequestMessage.ToString()) + ")");
        }
    }

    /// <summary>
    ///  <title>Logger Class class</title>
    ///  <description></description>
    ///  <copyRight>Copyright (c) 2012</copyRight>
    ///  <company>IronOne Technologies (Pvt)Ltd</company>
    ///  <createdOn>2012-</createdOn>
    ///  <author></author>
    ///  <modification>
    ///     <modifiedBy></modifiedBy>
    ///      <modifiedDate></modifiedDate>
    ///     <description></description>
    ///  </modification>
    /// </summary>
    public class Logger
    {
        public log4net.Core.Level Level { get; set; }
        private log4net.ILog logger;

        public Logger(log4net.ILog log)
        {

            logger = log;
            Level = ((log4net.Repository.Hierarchy.Logger)logger.Logger).Level;
        }

        public void Log(object message, Exception exception)
        {
            Type type = logger.GetType();
       
            logger.Logger.Log(type, Level, message, exception);
        }

        public void Log(object message)
        {
            this.Log(message, null);
        }
    }

    /// <summary>
    ///  <title>LogPoint Enum</title>
    ///  <description>Enum containing different Log points and statuses</description>
    ///  <copyRight>Copyright (c) 2012</copyRight>
    ///  <company>IronOne Technologies (Pvt)Ltd</company>
    ///  <createdOn>2012-</createdOn>
    ///  <author></author>
    ///  <modification>
    ///     <modifiedBy></modifiedBy>
    ///      <modifiedDate></modifiedDate>
    ///     <description></description>
    ///  </modification>
    /// </summary>
    public enum LogPoint
    {
        Entry = 0,
        Success,
        FileUploaded,
        Failure
    }
}